/*
  Author: xiaokai 
        - email: xiaokai.c@foxmail.com 
        - gitee: https://gitee.com/xiaokaiC
*/ 

#include "dotMap.h"

DotMapClass::DotMapClass(uint8_t (*cache)[PIXEL_WIDTH/8], uint8_t (*prepCache)[PIXEL_WIDTH/8])
:_ver_offset(0)
,_hor_offset(0)
,_cache(cache)
,_prepCache(prepCache)
{
}

void DotMapClass::scrollCacheLeft(void){
	uint8_t c_hbit[PIXEL_WIDTH/8];
	uint8_t p_hbit[PIXEL_WIDTH/8];
	int i,j;  
	for(j = 0; j < PIXEL_HEIGHT; j++){
		for(i = 0; i < PIXEL_WIDTH/8; i++){
			c_hbit[i] = _cache[j][i]&0x80;
			_cache[j][i] <<= 1;
		  p_hbit[i] = _prepCache[j][i]&0x80;
			_prepCache[j][i] <<= 1;
	  }
   
    for(i = 0; i < PIXEL_WIDTH/8-1; i++){
       _cache[j][i] = _cache[j][i] |(c_hbit[i+1]>>7);
       _prepCache[j][i] = _prepCache[j][i] |(p_hbit[i+1]>>7);
    }
    _cache[j][PIXEL_WIDTH/8-1] = _cache[j][PIXEL_WIDTH/8-1] | (p_hbit[0]>>7);
    _prepCache[j][PIXEL_WIDTH/8-1] = _prepCache[j][PIXEL_WIDTH/8-1] | (c_hbit[0]>>7);
	}
 
	_hor_offset-=1; 	
}

void DotMapClass::scrollCacheRight(void){
  uint8_t c_lbit[PIXEL_WIDTH/8];
  uint8_t p_lbit[PIXEL_WIDTH/8];
  int i,j;  
  for(j = 0; j < PIXEL_HEIGHT; j++){
    for(i = 0; i < PIXEL_WIDTH/8; i++){
      c_lbit[i] = _cache[j][i]&0x01;
      _cache[j][i] >>= 1;
      p_lbit[i] = _prepCache[j][i]&0x01;
      _prepCache[j][i] >>= 1;
    }
    
    for(i = 0; i < PIXEL_WIDTH/8-1; i++){
       _cache[j][i+1] = _cache[j][i+1] |(c_lbit[i]<<7);
       _prepCache[j][i+1] = _prepCache[j][i+1] |(p_lbit[i]<<7);
    }
    _cache[j][0] = _cache[j][0] | (p_lbit[PIXEL_WIDTH/8-1]<<7);
    _prepCache[j][0] = _prepCache[j][0] | (c_lbit[PIXEL_WIDTH/8-1]<<7);
  }

  _hor_offset+=1; 	
}
void DotMapClass::scrollCacheUp(void){
	uint8_t c_ubyte[PIXEL_WIDTH/8];
    uint8_t p_ubyte[PIXEL_WIDTH/8];
    int i,j;

    for(i = 0; i < PIXEL_WIDTH/8; i++){
      c_ubyte[i] = _cache[0][i];
      p_ubyte[i] = _prepCache[0][i];  
    }
    for(j = 0; j < PIXEL_HEIGHT-1; j++)
    {
       for(i = 0; i < PIXEL_WIDTH/8; i++){
          _cache[j][i] = _cache[j+1][i];
          _prepCache[j][i] = _prepCache[j+1][i];  
       }   
    }
    for(i = 0; i < PIXEL_WIDTH/8; i++){
      _cache[PIXEL_HEIGHT-1][i] = p_ubyte[i];
      _prepCache[PIXEL_HEIGHT-1][i] = c_ubyte[i];  
    }
    
    _ver_offset += 1;
}
void DotMapClass::scrollCacheDown(void){
	uint8_t c_dbyte[PIXEL_WIDTH/8];
    uint8_t p_dbyte[PIXEL_WIDTH/8];
    int i,j;

    for(i = 0; i < PIXEL_WIDTH/8; i++){
      c_dbyte[i] = _cache[PIXEL_HEIGHT-1][i];
      p_dbyte[i] = _prepCache[PIXEL_HEIGHT-1][i];  
    }
    for(j = PIXEL_HEIGHT-1; j > 0; j--)
    {
       for(i = 0; i < PIXEL_WIDTH/8; i++){
          _cache[j][i] = _cache[j-1][i];
          _prepCache[j][i] = _prepCache[j-1][i];  
       }   
    }
    for(i = 0; i < PIXEL_WIDTH/8; i++){
      _cache[0][i] = p_dbyte[i];
      _prepCache[0][i] = c_dbyte[i];  
    }
    _ver_offset -= 1;
}

bool DotMapClass::isPrepCacheUpdate(void){
	  if (_ver_offset > PIXEL_HEIGHT-1 || _ver_offset < -PIXEL_HEIGHT+1){
      _ver_offset = 0;
	    return true;
	  }
    if(_hor_offset > PIXEL_WIDTH-1 || _hor_offset < -PIXEL_WIDTH+1){
      _hor_offset = 0;
      return true;
    }
    return false;
}

void DotMapClass::cleanOffset(void){
   _ver_offset = 0;
   _hor_offset = 0;
}
